#pragma once
#include <vector>
#include "Common.h"

class CMonitorProcess
{
public:
	CMonitorProcess(const std::string& vTargetProcessName, const std::string& vTargetCrashPath);
	~CMonitorProcess();
	static void dumpSolutionDir(std::string& vioSolutionDir);
	static void createMonitorProcessInstance(const std::string& vTargetProcessName, const std::string& vTargetCrashPath);
	static void deleteMonitorProcessInstance();
	static CMonitorProcess* getMonitorProcessInstance();

	void createWindowAndLoop();

#ifdef _TEST
	bool getIsProcessCrashed() { return m_IsProcessCrashed; }
#endif

private:
	friend LRESULT WindowProcW(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK StaticWindowProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	static DWORD __stdcall __crashReportingThreadProc(LPVOID pThis);
	LRESULT __receiveProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

	//Record Mode
	void __onStartRecord(MessageProcess::EStatusType vType);
	void __onReceiveMessage(bool vIsEndOfSend = false);
	void __onEndRecord();
	void __onStatusChanged(MessageProcess::EStatusType vType);
	//Test Mode
	DWORD __run();
	void __handleCrash();
	bool __copyMiniDump(const std::string& vFolderPath);
	void __dumpMessageQueue(const std::string& vFolderPath);
	void __dumpUECrashFolderPath(std::string& vioUECrashPath);

	//Record Mode
	bool m_IsRunning = true;
	bool m_IsRelease = false;
	//Test Mode
	DWORD m_ThreadId = -1;
	HANDLE m_ThreadHandle = nullptr;
	std::string m_TargetProcessName;
	std::string m_TargetCrashPath;

	MessageProcess::EStatusType m_StatusType;
	std::vector<MessageProcess::SMessage> m_MessageQueue;

	HWND m_WindowHandle = NULL;
	LPVOID m_SharedMemory = NULL;
	HANDLE m_SharedMemoryHandle = NULL;
	HANDLE m_FirstSenderSemaphore = NULL;
	HANDLE m_FirstReceiverSemaphore = NULL;
	HANDLE m_SecondSenderSemaphore = NULL;
	HANDLE m_SecondReceiverSemaphore = NULL;
};